<?php /** sql语句生成器 **/
require_once 'CommonMethods.php';
class SQLBuilder{
    /** 数据库sql参数 **/
    private const SELECT = "select";
    private const UPDATE = "update";
    private const DELETE = "delete from";
    private const INSERT = "insert into";
    /** 数据库语句参数 **/
    private string $table; // 数据库表
    private string $filter; // 过滤信息
    private string $set; // 数据更新
    private string $where; // 条件
    private string $values; // 插入值

    /** 构造方法, 传入一个 table *
     * @param string $table
     */
    public function __construct(string $table = ""){
        /* 判空 */
        if( CommonMethods::isEmpty($table) )
            throw new Exception("数据库表必须初始化");
        $this->table = $table;
        $this->filter = "*";
        $this->set = "";
        $this->where = "";
        $this->values = "";
    }

    /** 修改变量的方法 *
     * @param string $filter
     * @return SQLBuilder
     */
    public function filter(string $filter = "*"): SQLBuilder{
        $this->filter = $filter;
        return $this;
    }
    public function set(string $set = ""): SQLBuilder{
        $this->set = $set;
        return $this;
    }
    public function where(string $where = ""): SQLBuilder{
        $this->where = $where;
        return $this;
    }
    public function values(string $values = ""): SQLBuilder{
        $this->values = $values;
        return $this;
    }

    /** 对象的终止方法, 返回一个处理好的sql语句 **/
    public function select(): string{
        return $this->sqlBuilder(self::SELECT);
    }
    public function insert(): string{
        return $this->sqlBuilder(self::INSERT);
    }
    public function delete(): string{
        return $this->sqlBuilder(self::DELETE);
    }
    public function update(): string{
        return $this->sqlBuilder(self::UPDATE);
    }

    /** sql语句解析器, 生成最终的sql语句
     * @param $type
     * @return string
     * @throws Exception
     */
    private function sqlBuilder($type): string{
        $sql = null;
        switch ($type){
            /* 查询语句 */
            case self::SELECT:
                /* 使用处理器 */
                $this->selectResolver($sql);
                break;
            /* 增加 */
            case self::INSERT:
                /* 使用处理器 */
                $this->insertResolver($sql);
                break;
            /* 增加 */
            case self::DELETE:
                /* 使用处理器 */
                $this->deleteResolver($sql);
                break;
            /* 增加 */
            case self::UPDATE:
                /* 使用处理器 */
                $this->updateResolver($sql);
                break;
        }
        return $sql;
    }

    /** 处理查询语句的处理器 *
     * @param $sql
     * @throws Exception
     */
    private function selectResolver(&$sql){
        /* 过滤消息是否为空 */
        if( CommonMethods::isEmpty($this->filter) )
            throw new Exception("过滤条件不能为空");
        $sql = self::SELECT." ".$this->filter." from ".$this->table;
        /* 判断是否有条件 */
        if( !CommonMethods::isEmpty($this->where) )
            $sql = $sql." where ".$this->where;
    }
    /** 处理插入语句的处理器 *
     * @param $sql
     * @throws Exception
     */
    private function insertResolver(&$sql){
        /* 判断数据值是否为空 */
        if( CommonMethods::isEmpty($this->values) )
            throw new Exception("插入值不能为空");
        /*  */
        $sql = self::INSERT." ".$this->table." values(".$this->values.")";
    }
    /** 处理删除语句的处理器 *
     * @param $sql
     * @throws Exception
     */
    private function deleteResolver(&$sql){
        /* 判断条件是否为空 */
        if( CommonMethods::isEmpty($this->where) )
            throw new Exception("删除语句最好要个条件");
        $sql = self::DELETE." ".$this->table." where ".$this->where;
    }
    /** 处理更新语句的处理器 *
     * @param $sql
     * @throws Exception
     */
    private function updateResolver(&$sql){
        /* 判断修改是否为空 */
        if( CommonMethods::isEmpty($this->set) )
            throw new Exception("更新语句需要修改信息");
        if( CommonMethods::isEmpty($this->where) )
            throw new Exception("更新语句需要条件");
        $sql = self::UPDATE." ".$this->table." set ".$this->set." where ".$this->where;
    }
}